// logger中间件
// export function logger({ getState, dispatch }) {
//   return function (next) {  //next = store.dispatch
//     //为了实现中间件的级联，调用下一个中间件
//     return function (action) {
//       //这才就是我们改造后的dispatch方法了
//       console.log("prev state", getState());
//       next(action); //如果你只有一个中间件的话，next就是原始的store.dispatch(action)
//       console.log("next state", getState());
//       return action;
//     };
//   };
// }


// function compose(...chain) {
//   if (!chain.length) return (v) => v;
//   if (chain.length === 1) {
//     return chain[0];
//   }
//   return chain.reduce((pre, cur) => {
//     return function (...args) {
//       return pre(cur(args));
//     };
//   });
// }
function compose(...funcs){
  return funcs.reduce((a,b)=>(...args)=>a(b(...args)));
}


export function applyMiddleware(...middlewares) {
  return function (createStore) {
      return function (reducer,preloadedState) {
          let store = createStore(reducer,preloadedState);
          let dispatch;
          let middlewareAPI = {
              getState: store.getState,
              dispatch: (action) => dispatch(action)
          }
          // 中间件运行流程：
          // 包装的时候，从右向左
          // const [promise, thunk, logger] = chain
          // dispatch = promise(thunk(logger(store.dispatch)))
          // 调用的时候，从左向右
          // promise, thunk, logger
          let chain = middlewares.map(middleware => middleware(middlewareAPI));
          // 重写dispatch = action
          dispatch = compose(...chain)(store.dispatch);
          return {
              ...store,
              dispatch
          }
      }
  }
}

export function logger({ getState, dispatch }) {
  return function (next) {
    return function (action) {
      console.log("prev state", getState());
      next(action);
      console.log("next state", getState());
    };
  };
}

export function thunk({ getState, dispatch }) {
  return function (next) { //重写之前的dispatch
    return function (action) { //重写之后的dispatch
      // action只能是普通对象
      // 现在可以是函数
      // 函数的话，会先执行action(dispatch, getState)，即外部传入的异步操作
      // 然后再执行next(action)
      if (typeof action === "function") {
        // 不能使用next，而要使用切片（重写）后的store.dispatch
        // next是指向最原始的store.dispatch,只能接受普通对象
        /**
          let store = createStore(reducer,preloadedState);
          dispatch = logger(store)(store.dispatch);
          使用切片（重写）后的store.dispatch = return function(action)
            return {
                ...store,
                dispatch
            };
        */
        // const store = applyMiddleware(logger)(createStore)(reducer)
        // store.dispatch 就是重写的dispatch，可以支持函数、promise等
        return action(dispatch, getState);
      }
      return next(action);
    };
  };
}

// export function promise({ getState, dispatch }) {
//     return function(next) {
//         return function(action) {
//             if(typeof action.then === "function") {
//                 return action.then((newAction => dispatch(newAction)))
//             }
//             return next(action)
//         }
//     }
// }
export function promise({ getState, dispatch }) {
  return function (next) {
    return function (action) {
      if (action.then && typeof action.then === "function") {
        action.then(dispatch).catch(dispatch);
      } else if (action.payload && typeof action.payload.then === "function") {
        action.payload
          .then((result) => dispatch({ ...action, payload: result }))
          .catch((error) => {
            dispatch({ ...action, payload: error, error: true });
            return Promise.reject(error);
          });
      } else {
        next(action);
      }
    };
  };
}